﻿using UnityEngine;
using System.Collections;
using System.IO;
using System.Xml;
using System;
using System.Collections.Generic;

/*
 * LevelLoader build level from target xml file.
 * xml filepath is rewrite string xmlPath in unity editor.
*/

public class LevelLoader : MonoBehaviour {
	public string xmlPath;
	public Rythem rythem;
	private List<SectionTmpl> secTmplList; 

	// Use this for initialization
	void Start () {
		secTmplList = new List<SectionTmpl> ();
		Load ();
	}

	// Update is called once per frame
	void Update () {

	}

	void Load()
	{
		XmlDocument xmlDoc = new XmlDocument ();

		TextAsset t = Resources.Load(xmlPath) as TextAsset;

		xmlDoc.Load(new MemoryStream(t.bytes));

		XmlElement rythemInfo = xmlDoc.SelectSingleNode ("music/rythem") as XmlElement;
		
		rythem.Meter = 60.0f / System.Int32.Parse(rythemInfo.GetAttribute ("meterpermin"));

		XmlNodeList templateList = xmlDoc.SelectSingleNode ("music/nodeTemplate").ChildNodes;

		foreach(XmlElement tmpl in templateList)
		{
			if(tmpl.Name == "node")
			{
				ResverTemplate(tmpl);
			}
		}


		XmlNodeList nodeList = xmlDoc.SelectSingleNode("music/rythem").ChildNodes;

		foreach(XmlElement xe in nodeList)
		{
			if(xe.Name == "section")
			{
				ResverSection(xe);
			}
		}
	}

	void ResverTemplate(XmlElement xelmnt)
	{
		SectionTmpl newSecTmpl = new SectionTmpl ();

		string tmplid = xelmnt.GetAttribute("id");

		newSecTmpl.ID = System.Int32.Parse (tmplid);

		XmlNodeList nodeList = xelmnt.ChildNodes;

		foreach(XmlElement xe in nodeList)
		{
			if(xe.Name == "event")
			{
				newSecTmpl.AddEvent(ParseEvent(xe));
			}
		}

		secTmplList.Add (newSecTmpl);
	}

	// analazy section info
	void ResverSection(XmlElement xelmnt)
	{
		Section newSec = new Section ();

		string notetime = xelmnt.GetAttribute ("notetime");
		newSec.Notetime = System.Int32.Parse (notetime);

		XmlNode xe = xelmnt.FirstChild;

		if (null != xe)
		{
			PickSuitableSecTmpl(newSec, xe as XmlElement);	
		}

		rythem.AddSection (newSec);
	}

	// pickup a random template section
	bool PickSuitableSecTmpl(Section sec, XmlElement xelmnt)
	{
		if("nodepool" == xelmnt.Name)
		{
			string idlist = xelmnt.GetAttribute("idpool");

			string[] spId = idlist.Split('|');

			int id = UnityEngine.Random.Range(0, spId.Length);

			int tmplId = System.Int32.Parse(spId[id]);

			foreach(SectionTmpl tp in secTmplList)
			{
				if(tp.ID == tmplId)
				{
					sec.tmpl = tp.Clone() as SectionTmpl;

					return true;
				}
			}
		}

		return false;
	}

	AnimEventTmpl ParseEvent(XmlElement xe)
	{
		string notetime = xe.GetAttribute("notetime");
		string funcname = xe.GetAttribute ("functionName");
		string paramValue = xe.GetAttribute ("paramValue");

		AnimEventTmpl evt = new AnimEventTmpl ();
		evt.time = System.Single.Parse (notetime) * rythem.Meter;
		evt.functionName = funcname;
		evt.stringParameter = paramValue;

		PressJudgment pj = FindObjectOfType<PressJudgment> ();

		if (funcname.StartsWith ("Time2")) {
			evt.time = evt.time - pj.fail_error_allowed;
		}

		return evt;
	}
}
